﻿using Microsoft.AspNetCore.Authentication.BearerToken;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Quickly.Identity.Services
{
    public class Login
    {
        public static async Task<Results<Ok<AccessTokenResponse>, EmptyHttpResult, ProblemHttpResult>> ExecuteAsync(
            [FromBody] LoginRequest login, 
            [FromQuery] bool? useCookies, 
            [FromQuery] bool? useSessionCookies, 
            [FromServices] IServiceProvider sp, 
            CancellationToken cancellationToken)
        {
            var signInManager = sp.GetRequiredService<SignInManager<AppUser>>();

            var useCookieSchema = (useCookies == true) || (useSessionCookies == true);
            var isPersistent = (useCookies == true) && useSessionCookies != true;

            signInManager.AuthenticationScheme = useCookieSchema ? IdentityConstants.ApplicationScheme : IdentityConstants.BearerScheme;

            var result = await signInManager.PasswordSignInAsync(login.Email, login.Password, isPersistent, true);

            if (result.RequiresTwoFactor)
            {
                if (string.IsNullOrEmpty(login.TwoFactorCode) == false)
                {
                    result = await signInManager.TwoFactorAuthenticatorSignInAsync(login.TwoFactorCode, isPersistent, rememberClient: isPersistent);
                }
                else if (string.IsNullOrEmpty(login.TwoFactorRecoveryCode) == false)
                {
                    result = await signInManager.TwoFactorRecoveryCodeSignInAsync(login.TwoFactorRecoveryCode);
                }
            }

            if (result.Succeeded == false)
            {
                return TypedResults.Problem(result.ToString(), statusCode: StatusCodes.Status401Unauthorized);
            }

            return TypedResults.Empty;
        }
    }
}
